package concurrency

import (
	"fmt"
	"sync"
)

// 流水线工序一 采购原材料
func buy(n int) <-chan string {
	out := make(chan string)
	go func() {
		defer close(out)
		for i := 1; i <= n; i++ {
			out <- fmt.Sprint("配件", i)
		}
	}()
	return out
}

//工序2组装 将购买的材料组装 组装函数 build 有一个 channel 类型的参数 in，用于接收配件进行组装，组装后的手机放到 channel 类型的变量 out 中返回
func build(in <-chan string) <-chan string {
	out := make(chan string)
	go func() {
		defer close(out)
		for c := range in {
			out <- "组装(" + c + ")"
		}
	}()
	return out
}

//工序3打包
func pack(in <-chan string) <-chan string {
	out := make(chan string)
	go func() {
		defer close(out)
		for c := range in {
			out <- "打包(" + c + ")"
		}
	}()
	return out
}

// 合并 扇入函数 <- chan string 表示只能从通道接收值
func merge(ins ...<-chan string) <-chan string {
	var wg sync.WaitGroup
	out := make(chan string)
	// 把一个channel中的数据发送到out
	p := func(in <-chan string) {
		defer wg.Done()
		for c := range in {
			out <- c
		}
	}

	wg.Add(len(ins))

	// 扇入 goroutin处理多个channel中的数据
	for _, cs := range ins {
		go p(cs)
	}

	// 等待所有输入的数据ins处理完再关闭out
	go func() {
		wg.Wait()
		close(out)
	}()
	return out
}
